/**
 * @file 02_template_matrix.cpp
 * @author chatgpt + codegeex
 * @brief 注释都是用codegeex自动生成的，代码是用chatgpt生成的
 * @version 0.1
 * @date 2023-09-06
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#include <iostream>
#include <vector>

template <typename T, std::size_t Rows, std::size_t Cols>
class Matrix {
public:
    // 构造函数，用于初始化矩阵
    Matrix() : data(Rows, std::vector<T>(Cols, T())) {}

    // 重载 () 运算符以访问矩阵元素
    T& operator()(std::size_t row, std::size_t col) {
        return data[row][col];
    }

    // 常量版本的 () 运算符
    const T& operator()(std::size_t row, std::size_t col) const {
        return data[row][col];
    }

    // 打印矩阵内容
    void print() const {
        for (std::size_t i = 0; i < Rows; ++i) {
            for (std::size_t j = 0; j < Cols; ++j) {
                std::cout << data[i][j] <<'';
            }
            std::cout << '\n';
        }
    }

    // 矩阵乘法
    template <std::size_t OtherCols>
    Matrix<T, Rows, OtherCols> operator*(const Matrix<T, Cols, OtherCols>& other) const {
        Matrix<T, Rows, OtherCols> result;

        // 遍历矩阵的行
        for (std::size_t i = 0; i < Rows; ++i) {
            // 遍历矩阵的列
            for (std::size_t j = 0; j < OtherCols; ++j) {
                // 遍历矩阵的每一行
                for (std::size_t k = 0; k < Cols; ++k) {
                    // 计算结果矩阵的每一行的每一列的和
                    result(i, j) += data[i][k] * other(k, j);
                }
            }
        }

        return result;
    }

private:
    std::vector<std::vector<T>> data;
};

int main() {
    Matrix<int, 2, 3> matrix1;
    matrix1(0, 0) = 1;
    matrix1(0, 1) = 2;
    matrix1(0, 2) = 3;
    matrix1(1, 0) = 4;
    matrix1(1, 1) = 5;
    matrix1(1, 2) = 6;

    Matrix<int, 3, 2> matrix2;
    matrix2(0, 0) = 7;
    matrix2(0, 1) = 8;
    matrix2(1, 0) = 9;
    matrix2(1, 1) = 10;
    matrix2(2, 0) = 11;
    matrix2(2, 1) = 12;

    Matrix<int, 2, 2> result = matrix1 * matrix2;

    std::cout << "Matrix 1:\n";
    matrix1.print();

    std::cout << "\nMatrix 2:\n";
    matrix2.print();

    std::cout << "\nMatrix 1 * Matrix 2:\n";
    result.print();

    return 0;
}